package com.authstr.auth.jwt;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;


public class JwtUtil {


    //短 过期时间60分钟
    private static final long SHORT_EXPIRE_TIME = 1000 * 60 * 60*24*7;

    //长 过期时间7天
    private static final long LONG_EXPIRE_TIME = 1000 * 60 * 60 * 24 * 7;

    //刷新token的时间节点,token有效时间低于该时间将刷新token  15分钟
    private static final long REFRESH_COUNT_DOWN = 1000 * 60 * 15*4;


    /**
     * 校验token是否正确
     *
     * @param token    密钥
     * @param username 登录名
     * @param password 密码
     * @return
     */
    public static boolean verify(String token, String username, String password) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(password);

            JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();

            DecodedJWT jwt = verifier.verify(token);

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取用户名
     *
     * @param credentials
     * @return
     */
    public static String getAccount(String credentials) {
        try {
            DecodedJWT jwt = JWT.decode(credentials);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成签名
     *
     * @param username
     * @param password
     * @return
     */
    public static String sign(String username, String password) {
        // 指定过期时间
        Date date = new Date(System.currentTimeMillis() + SHORT_EXPIRE_TIME);

        Algorithm algorithm = Algorithm.HMAC256(password);

        return JWT.create()
                .withClaim("username", username)
                .withExpiresAt(date)
                .sign(algorithm);
    }

    /**
     * token的剩余有效期,单位毫秒
     * @param token
     * @return
     */
    public static Long getRemainingTime(String token) {
        try{
            DecodedJWT jwt = JWT.decode(token);
            Long remainingTime=jwt.getExpiresAt().getTime()-System.currentTimeMillis();
            return remainingTime;
        }catch (Exception e){
            return -1l;
        }
    }

    /**
     * 是否应刷新tonken
     * @param token
     * @return
     */
    public static Boolean isRefreshToken(String token){
        Long remainingTime=getRemainingTime(token);
        return null!=remainingTime && remainingTime>0 && remainingTime<=REFRESH_COUNT_DOWN;
    }

    /**
     * 在cookie和相应头设置token
     * @param response
     * @param token
     */
    public static void cookieAndHeaderSetToken(HttpServletResponse response,String token){
        Cookie cookie = new Cookie("token",token);
        cookie.setPath( "/");
        response.addCookie(cookie);
        response.setHeader("token",token);
    }

    /**
     * 在cookie和相应头 获取 token
     * @param httpServletRequest
     */
    public static String  cookieAndHeaderGetToken(HttpServletRequest  httpServletRequest){
        //获取请求头的token
        String token = httpServletRequest.getHeader("token");
        if(!StringUtils.hasText(token)){
            //请求头没有,尝试从cookie获取token
            Cookie[] cookies=httpServletRequest.getCookies();
            if(null!=cookies&&cookies.length!=0){
                i:for(Cookie cookie:cookies){
                    if(cookie.getName().equalsIgnoreCase("token")){
                        token=cookie.getValue();
                        break i;
                    }
                }
            }
        }
        return token;
    }



}
